package com.zhoukun.cloud.controller;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.zhoukun.cloud.service.userService;
import com.zhoukun.cloud.CommentRest;
import com.zhoukun.cloud.user;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

/**
 * @author zhoukun 86547462@qq.com
 * @version 1.0
 * @date 2020/10/24 19:44
 */
@RestController
@Slf4j
@RefreshScope //自动刷新只能刷新 @RefreshScope 注解下的配置，一些特殊配置，如数据库等，需要同样先设置数据库链接ConfigServer类，然后通过加 @RefreshScope 注解方式
@DefaultProperties(defaultFallback = "defaultGlobalFallback") //统一的降级方法
public class PaymentController {
    @Autowired
    userService service;


    //查询
    @GetMapping("/payment/query")
    @HystrixCommand //没有特别指明用统一的
    public CommentRest query()
    {
        return new CommentRest()
                .setCode(200)
                .setMessage("success")
                .setData(service.list());
    }


    //查询单个
    @GetMapping("/payment/queryById/{Id}")
    @HystrixCommand //没有特别指明用统一的
    public CommentRest queryById(@PathVariable String Id)
    {
        int i=10/0;
        return new CommentRest()
                .setCode(200)
                .setMessage("success")
                .setData(service.getById(Id));
    }

    //修改余额
    @GetMapping("/payment/banUP/{Id}/{money}")
    @HystrixCommand//没有特别指明用统一的
    public CommentRest banUP(@PathVariable String Id,
                                @PathVariable BigDecimal money)
    {

        UpdateWrapper<user> wrapper=new UpdateWrapper<user>();
        wrapper.eq("id",Id);
        return new CommentRest()
                .setCode(200)
                .setMessage("success")
                .setData(service.update(new user().setBalance(money),wrapper));
    }

    //延时测试
    @GetMapping("/payment/outTime")
    @HystrixCommand//没有特别指明用统一的
    public CommentRest outTime()  {
        try {
            TimeUnit.SECONDS.sleep(3);//暂停3秒
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return new CommentRest().setCode(200)
                .setMessage("success")
                .setData("时间测试");
    }


    //服务降级测试
    @GetMapping("/payment/demotion/{num}")
    @HystrixCommand(fallbackMethod = "demotionfallback",commandProperties = {
            //规定3秒以内是正常的业务逻辑，超出直接走demotionfallback备用方法
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")

    })
    public CommentRest demotion(@PathVariable int num) throws Exception {
        if(num>0)
        {
            return new CommentRest().setCode(200)
                    .setMessage("success")
                    .setData("qwq,服务正常！");
        }else{
            throw new Exception("不能为负数，出现异常"+num);
        }
    }
    public CommentRest demotionfallback(@PathVariable int num) throws Exception {

            return new CommentRest().setCode(200)
                    .setMessage("err")
                    .setData(">_< ！  ，当前服务出现异常情稍后再试....");

    }


    //服务熔断测试
    @GetMapping("/payment/fusing/{num}")
    @HystrixCommand(commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
            // 至少有3个请求才进行熔断错误比率计算（请求次数）
            /**
             * 设置在一个滚动窗口中，打开断路器的最少请求数。
             比如：如果值是20，在一个窗口内（比如10秒），收到19个请求，即使这19个请求都失败了，断路器也不会打开。
             */
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
            //当出错率超过50%后熔断器启动
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),
            // 熔断器工作时间，超过这个时间，先放一个请求进去，成功的话就关闭熔断，失败就再等一段时间
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000")
    })
    public CommentRest fusing(@PathVariable int num) throws Exception {
        if(num>0)
        {
            return new CommentRest().setCode(200)
                    .setMessage("success")
                    .setData("qwq,服务正常！");
        }else{
            throw new Exception("不能为负数，出现异常"+num);
        }
    }





    /**
     * 没有特别指明就用统一的，
     * @return
     */
    public CommentRest defaultGlobalFallback()
    {
        return new CommentRest().setCode(200)
            .setMessage("err")
            .setData("Q_Q ！，Global服务器繁忙情稍后再试....");
    }

    //查看当前环境
    @Value("${info.environment}")
    String environment;
    @GetMapping("/payment/environment")
    public String environment(){
        return environment;
    }
}
